package org.komarichin.filters.gzip;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * User: Mykhaylo Komarichyn
 * Date: 18.02.2010
 * Time: 16:22:07
 */
public class GZIPFilter implements Filter {
    private static final Logger log = LoggerFactory.getLogger(GZIPFilter.class);

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

        if (req instanceof HttpServletRequest) {
            HttpServletRequest request = (HttpServletRequest) req;
            HttpServletResponse response = (HttpServletResponse) res;


            String s = request.getRequestURI();
            if (excluded(s)) {
                chain.doFilter(req, res);
            } else if (isGZIPSupported(request)) {
                if (log.isDebugEnabled()) {
                    log.debug("GZIP supported, compressing response");
                }

                GZIPResponseWrapper wrappedResponse = new GZIPResponseWrapper(response);

                chain.doFilter(req, wrappedResponse);
                wrappedResponse.finishResponse();

                return;
            }

            chain.doFilter(req, res);
        }
    }

    private String excluded;

    private boolean excluded(String s) {
        return !(s == null || excluded == null) && excluded.indexOf(s + ",") >= 0;
    }

    private static final String EXCLUDE = "exclude";

    /**
     * Convenience method to test for GZIP cababilities
     *
     * @param req The current user request
     * @return boolean indicating GZIP support
     */
    private boolean isGZIPSupported(HttpServletRequest req) {
        String browserEncodings = req.getHeader("accept-encoding");
        return ((browserEncodings != null) && (browserEncodings.indexOf("gzip") != -1));
    }

    public void init(FilterConfig filterConfig) {
        //no action here
        log.info("init gzip filter");
        if ((excluded = filterConfig.getInitParameter(EXCLUDE)) != null) {
            excluded += ",";
        }
    }

    public void destroy() {
        //no action here
        log.info("destroy gzip filter");
    }

}
